@! syntax.fw  -- first edit Mon Dec 12 1994        -- by Karl Prott
@! $Id: syntax.fw,v 1.4 1996/02/28 17:25:45 kalle Exp $
@p typesetter = tex
@p maximum_input_line_length = infinity

@! because sign '@' is needed below
@=~

\documentstyle[11pt,a4]{article}
\setlength{\textwidth}{16.5cm}
\setlength{\textheight}{25cm}
\setlength{\parindent}{0mm}
\setlength{\parskip}{6pt}

\setlength{\voffset}{-1in}
\setlength{\hoffset}{-0.5in}
% Defaults for offset
% \setlength{\voffset}{0pt}
% \setlength{\hoffset}{0pt}


\begin{document}


\section{Lexical Structure}

Names and comments are defined as in C whereas strings and cardinal
numbers are defined as in Pascal. Token {\tt String} is used for
literal terminals and connections. Token {\tt NAME} is used for
nonliteral terminals, nonterminals, the grammar name and for rule
names.

Module {\tt mkidnwod.[hc]} exports the function {\tt mkidnwod()},
which is nearly identical to the library function {\tt mkidn()}. The
only difference is, that the delimiters {\tt '} are not stored.

~O~<pgs2cmr.gla~>~{
/* C_IDENTIFIER with mkidnwod instead of mkidn */
NAME:   $[a-zA-Z_][a-zA-Z_0-9]*         [mkidnwod]

/* PASCAL_STRING with mkidnwod instead of mkstr */
STRING:         $' (auxPascalString)    [mkidnwod]

CARDINAL:       PASCAL_INTEGER

/* Comments */
AWK_COMMENT
C_COMMENT
~}

~O~<mkidnwod.h~>~{
/* mkidnwod: mkidn WithOut Delimiters */
/* Make an internal string value from a character string
 * This function uses the original function 'mkidn' but
 * leaves the delimiters (first and last character) out.
 * The value of *class will NOT be modified!
 */
extern  void
#if defined(__STDC__) || defined(__cplusplus)
        mkidnwod(char *start, int length, int *class, int *intrinsic);
#else
        mkidnwod();
#endif
~}

~O~<mkidnwod.c~>~{
#include "idn.h"
#include "mkidnwod.h"

void
#if defined(__STDC__) || defined(__cplusplus)
        mkidnwod(char *start, int length, int *class, int *intrinsic)
#else
        mkidnwod(start, length, class, intrinsic)
        char *start; int length, *class; int *intrinsic;
#endif
{
        int     dummy;

        dummy = *class;
        if ( *start == '\'')
                mkidn (start+1, length-2, &dummy, intrinsic);
        else
                mkidn (start, length, &dummy, intrinsic);
} /* of mkidnwod() */

~}


\section{Syntactic structure}

The encoding of the tokens {\tt (code\_part)}, the definition of an
end-of-file symbol {\tt (stop\_part)} and hints for the error
correction {\tt (err\_part)} are optional. The grammar part {\tt
  (grammar\_part)} is not optional, but may contain an empty list of
rules. A name for the grammar is optional too.

Rules may be in Extended Backus Nour Form. Increasing list of
operators: {\tt del\_op $\rightarrow$ alt\_op $\rightarrow$
  concatenation $\rightarrow$ mod\_op, \& $\rightarrow$ rep\_op, [x],
  (x)}. Rule names are optional.

The symbol {\tt (non)terminal} stands for (non)terminals, whereas
symbol {\tt t\_or\_nt} is used in places where it cannot be
distinguished syntactically whether it stands for a terminal or nonterminal.

The only eliminated chain rule is {\tt rhs : alt.} .

~O~<pgs2cmr.sym~>~{
rhs     ::= alt .
~}

'pgs\_root' represents a parser specification in pgs notation. `actpts\_root'
has been added for information about used free positions. The standard cola
frontend doesn't need these informations. Therefore `actpts\_root' derives
nothing.

~O~<pgs2cmr.con~>~{
root		: pgs_root actpts_root .
actpts_root     : .
pgs_root        : code_part stop_part err_part grammar_part .

code_part       : '$CODE' code_def_list
                  / .
code_def_list   : code_def* .
code_def        : terminal '=' CARDINAL '.' .

stop_part       : '$STOP' terminal '.' 
                  / '$STOP'
                  / .

err_part        : sepa_part bracket_part skip_part .
sepa_part       : '$SEPA' term_def_list
                  / .
bracket_part    : '$BRACKET' term_def_list
                  / .
skip_part       : '$SKIP' term_def_list
                  / .
term_def_list   : term_def* .
term_def        : terminal '.' .


grammar_part    : '$GRAMMAR' '=' grammarname start rule_list 
                  / '$GRAMMAR' start rule_list .

grammarname     : NAME .

start           : '<$START_SYMBOL>' sep_op nonterminal '.'
                  / .

rule_list       : rule* .
rule            : nonterminal sep_op rhs '.'
                  /  rulename '=' nonterminal sep_op rhs '.' .
rulename        : NAME .

rhs             : rhs del_op terminal
                  / alt .
alt             : alt alt_op elem_list
                  / elem_list .

elem_list       : (elem / connection / modification)* .
elem            : t_or_nt 
                  /  optelem 
                  /  '(' rhs ')' 
                  /  elem rep_op .
optelem         : '[' rhs ']'  .
modification    : mod_op terminal .
connection      : '&' STRING .

t_or_nt         : nonliteral
                  / literal .
nonterminal     : NAME .
terminal        : nonliteral 
                  / literal .
nonliteral      : NAME .
literal         : STRING .

sep_op          : ':'  /  '::=' .
alt_op          : '/'  /  '|' .
del_op          : '//' /  '||' .
mod_op          : '$'  /  '@' .
rep_op          : '*'  /  '+' .
~}

These rules are needed for a correct mapping between parsing grammar
and tree grammar because of introducing the symbols {\tt grammarname,
  rulename}.

~O~<pgs2cmr.lido~>~{
RULE : grammar_part ::=  '$GRAMMAR' '=' grammarname start rule_list END;
RULE : grammarname ::=  NAME END;

RULE : rule ::=  rulename '=' nonterminal sep_op rhs '.' END;
RULE : rulename ::= NAME END;
~}

\end{document}
